using System.Collections.Generic;
using UnityEngine;

public class TableTennisAIPlayer : TableTennisPlayerBase
{
	public bool testPing;

	public float pingTime;

	protected FlightInitialConditionsSearch search = new FlightInitialConditionsSearch();

	protected PhysicsBall ball;

	public bool showPoints;

	public float moveSpeed = 2f;

	public PlayerDB.AiPlayerDefinition aiDefinition = new PlayerDB.AiPlayerDefinition();

	public bool hasBackSpin;

	[Range(0.02f, 4f)]
	public float heightAboveNet = 0.2f;

	public FloatRange heightAboveNetRangeReturn = default(FloatRange);

	public FloatRange heightAboveNetRangeServe = default(FloatRange);

	public FloatRange strengthRange = default(FloatRange);

	[Range(-150f, 150f)]
	public float spin;

	public FloatRange spinRange = default(FloatRange);

	[Range(0f, 1f)]
	public float xRange = 0.5f;

	private Animator cachedAnimator_;

	private StoreItemsConfig.StoreItem racket_;

	public GaussParams hitTimingRange = new GaussParams
	{
		mean = 0.01281723f,
		sigma2 = 0.275162f
	};

	public Vector3 serveOffsetPosition;

	public float hitHeight = 0.98f;

	public float ballTossSpeed = 3.8f;

	protected Vector3 servePosition;

	protected MagnusForceAndAirResistanceSquaredBallFlight symFlight = new MagnusForceAndAirResistanceSquaredBallFlight();

	private bool isInServe;

	private float serveTossAnimSpeed = 2f;

	protected StoreItemsConfig.StoreItem shoe_;

	private float maxServeHeight = 2f;

	protected PlayerAnimationsController.HitPlan chosenHitPlan;

	public TTAiPlayerDefinition definition
	{
		get
		{
			return ScriptableObjectSingleton<TTAiPlayerDefinitions>.instance.GetDefinition(aiDefinition.index);
		}
	}

	public int scoreDifference
	{
		get
		{
			TableTennisClassic tableTennisClassic = base.match.gameType as TableTennisClassic;
			if (tableTennisClassic == null)
			{
				return 0;
			}
			return (int)tableTennisClassic.GetScoreDifference(base.teamTag);
		}
	}

	protected Animator cachedAnimator
	{
		get
		{
			if (cachedAnimator_ == null)
			{
				for (int i = 0; i < base.transform.childCount; i++)
				{
					Transform child = base.transform.GetChild(i);
					cachedAnimator_ = child.GetComponent<Animator>();
					if (cachedAnimator_ != null)
					{
						break;
					}
				}
			}
			return cachedAnimator_;
		}
	}

	public StoreItemsConfig.StoreItem racket
	{
		get
		{
			PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
			if (opponentDefinition == null)
			{
				return null;
			}
			if (racket_ == null)
			{
				racket_ = StoreItemsConfig.instance.FindItemWithId(opponentDefinition.racketId);
			}
			return racket_;
		}
	}

	public bool ballFlyingTowardsMe { get; protected set; }

	private Vector3 serveCentralPosition
	{
		get
		{
			return new Vector3(0.024f, 0f, 2.083f * (float)base.tableSide);
		}
	}

	public StoreItemsConfig.StoreItem shoe
	{
		get
		{
			if (shoe_ == null)
			{
				PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
				if (opponentDefinition != null)
				{
					shoe_ = StoreItemsConfig.instance.FindItemWithId(opponentDefinition.shoeId);
					GGDebug.DebugLog("Got shoe with id " + shoe_.name + " psn " + shoe_.previewSpriteName);
				}
				else
				{
					shoe_ = StoreItemsConfig.instance.GetItemsForType(StoreItemsConfig.StoreItem.ItemType.Shoe, true)[0];
				}
			}
			return shoe_;
		}
	}

	public override void AwaitServe()
	{
		base.kineticPlan.CancelAll();
		base.playerPosition = serveCentralPosition;
		CancelMovePlan();
	}

	public override bool IsInServe()
	{
		return isInServe;
	}

	public override void Init(int teamTag, int tableSide, TableTennisMatchController match, bool canAlwaysHit)
	{
		base.Init(teamTag, tableSide, match, canAlwaysHit);
		PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
		if (opponentDefinition != null)
		{
			aiDefinition.index = opponentDefinition.aiPlalyerDefinition.index;
		}
		TTAiPlayerDefinition tTAiPlayerDefinition = definition;
	}

	public override void StartServe(PhysicsBall ball)
	{
		CancelMovePlan();
		base.kineticPlan.CancelAllPendingElements();
		this.ball = ball;
		this.ball.ParentToObject(serveHand);
		this.ball.localPosition = serveOffsetPosition;
		ballFlyingTowardsMe = false;
		isInServe = true;
		float num = (serveCentralPosition - base.playerPosition).OnGround().magnitude / (0.5f * moveSpeed);
		base.playerPosition = serveCentralPosition;
		base.kineticPlan.CancelAll();
		DoStartServe();
	}

	private void StartMoveIntoServe()
	{
		CancelMovePlan();
		base.kineticPlan.CancelAll(false);
		animController.FillStartServePlan(serveCentralPosition, base.kineticPlan);
	}

	private void DoStartServe()
	{
		base.kineticPlan.CancelAllPendingElements();
		Debug.Log("Toss Ball In Air");
		animController.TossBallInAir(base.kineticPlan, serveTossAnimSpeed, OnStartServeThrowDelegate);
	}

	public virtual float GetSpeed(int numShotsInPoint)
	{
		PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
		float num = 0f;
		if (opponentDefinition == null)
		{
			return definition.GetSpeed(numShotsInPoint);
		}
		return shoe.GetSpeed((float)numShotsInPoint / opponentDefinition.enduranceMult) * opponentDefinition.speedMult;
	}

	public float GetJumpSpeed(int numShotsInPoint)
	{
		PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
		if (opponentDefinition == null)
		{
			return definition.GetJumpSpeed(numShotsInPoint);
		}
		return shoe.GetJumpSpeed(numShotsInPoint);
	}

	public override float GetSkillPoints(PlayerStatsManager.SkillType skillType)
	{
		PlayerDB.TournamentPlayer opponentDefinition = MatchParameters.InitParameters.opponentDefinition;
		if (opponentDefinition == null)
		{
			return base.GetSkillPoints(skillType) * MatchParameters.InitParameters.skillPointsScale + MatchParameters.InitParameters.skillPointsOffset;
		}
		return opponentDefinition.GetSkillValue((int)skillType) * MatchParameters.InitParameters.skillPointsScale + MatchParameters.InitParameters.skillPointsOffset;
	}

	private void CancelMovePlan()
	{
		movePlan.isActive = false;
		cachedAnimator.SetFloat("SpeedX", 0f);
		cachedAnimator.SetFloat("SpeedY", 0f);
	}

	public override void BallRemovedFromGame()
	{
		CancelMovePlan();
		base.kineticPlan.CancelAll(false);
	}

	private void OnStartServeThrowDelegate(KineticServeHitElement hit)
	{
		ball.transform.parent = null;
		float num = Mathf.Sqrt(-2f * Physics.gravity.y * (maxServeHeight - ball.position.y));
		HitAnimationInfo orCreateServeHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateServeHitAnimationByEnum(ServeHitAnimationsStateEnum.ServeHit);
		float y = orCreateServeHitAnimationByEnum.hitPosition.y;
		servePosition = base.playerPosition + base.kineticPlan.cachedTransform.rotation * orCreateServeHitAnimationByEnum.hitPosition.OnGround();
		servePosition.y = y;
		MathEx.NullPoints nullPoints = MathEx.FindParabolaNullPoints((0f - Physics.gravity.y) / 2f, 0f - num, y - ball.position.y);
		float max = nullPoints.Max;
		Vector3 velocity = (servePosition - ball.position).OnGround() / max;
		velocity.y = num;
		ball.StartServe(velocity);
		base.kineticPlan.CancelAllPendingElements();
		animController.FillServeToss(ServeHitAnimationsStateEnum.ServeHit, base.kineticPlan, OnTryServe, max / ball.framerateScale - base.kineticPlan.activeElement.durationTillEnd, false);
	}

	private void OnTryServe(KineticServeHitElement hit)
	{
		PhysicsBall physicsBall = ball;
		ShootBall(true);
		if (testPing)
		{
			float timeToStage = physicsBall.flightSequence.GetTimeToStage(physicsBall.flightSequence.LastStage());
			GGDebug.DebugLog(timeToStage);
			float gameTimescale = ((physicsBall.flightSequence.GetFirstStage() == physicsBall.flightSequence.LastStage()) ? 1f : (1f + pingTime * 0.001f / Time.timeScale / timeToStage));
			GGGameTime.gameTimescale = gameTimescale;
		}
	}

	public override void ReceiveBall(PhysicsBall ball)
	{
		this.ball = ball;
		ballFlyingTowardsMe = true;
		OnBallReturned();
	}

	public bool ShouldAttack()
	{
		Vector3 qualityWeight = new Vector3(definition.attackXWeight.Random(), 0f, definition.attackZWeight.Random());
		float num = GetDefensePositionQuality(qualityWeight: new Vector3(definition.defenseXWeight.Random(), 0f, definition.defenseZWeight.Random()), position: base.playerPosition);
		float defensePositionQuality = GetDefensePositionQuality(base.match.Other(this).playerPosition, qualityWeight);
		float num2 = defensePositionQuality * definition.defenseWeight.Random() - num * definition.attackWeight.Random();
		return num2 <= 0f;
	}

	protected float GetDefensePositionQuality(Vector3 position, Vector3 qualityWeight)
	{
		float num = 1.5f;
		float num2 = 2f;
		float num3 = (num - Mathf.Clamp(Mathf.Abs(position.x), 0f, num)) / num;
		float num4 = (Mathf.Abs(position.z) - Table.halfLength) / (Table.halfLength * num2);
		return (qualityWeight.x * num3 + qualityWeight.z * num4) / (qualityWeight.x + qualityWeight.z);
	}

	protected float GetAttackPositionQuality(Vector3 position, Vector3 qualityWeight)
	{
		float num = 1.5f;
		float num2 = 2f;
		float num3 = (num - Mathf.Clamp(Mathf.Abs(position.x), 0f, num)) / num;
		float num4 = (Mathf.Abs(position.z) - Table.halfLength) / (Table.halfLength * num2);
		return qualityWeight.x * num3 + qualityWeight.z * num4;
	}

	protected virtual void ShootBall(bool isServe = false, KineticElementHit hit = null)
	{
		ballFlyingTowardsMe = false;
		ball.HitOnServe();
		HitParamsDB.Hit hit2 = null;
		PlayerStatsManager.SkillType skillType = PlayerStatsManager.SkillType.Attack;
		PlayerStatsManager.SkillType skillType2 = PlayerStatsManager.SkillType.Attack;
		if (isServe)
		{
			hit2 = ScriptableObjectSingleton<HitParamsDB>.instance.GetHit(HitParamsDB.HitType.Serve);
		}
		else if (chosenHitPlan != null)
		{
			PlayerAnimationsController.HitAnimationParams hitParams = chosenHitPlan.hitParams;
			skillType = hitParams.skillType;
			hit2 = ScriptableObjectSingleton<HitParamsDB>.instance.GetHit(hitParams.type);
			skillType = PlayerStatsManager.SkillType.Defence;
			skillType2 = PlayerStatsManager.SkillType.Attack;
		}
		HitParameters hitParams2 = default(HitParameters);
		hitParams2.attackPoints = GetSkillPoints(PlayerStatsManager.SkillType.Attack);
		TableTennisPlayerBase tableTennisPlayerBase = base.match.Other(this);
		float num = definition.power.Random();
		FloatRange floatRange = ScriptableObjectSingleton<HitParamsDB>.instance.timing.GetRealRangeInSec(ball.flightSequence.flightTime);
		if (definition.realTimeTiming)
		{
			floatRange = ScriptableObjectSingleton<HitParamsDB>.instance.timing.timingInSecs;
		}
		float num2 = definition.timing.Random(scoreDifference) * floatRange.max;
		float num3 = GetSkillDifference(ball, num, hit2.type, skillType);
		if (num3 < 0f)
		{
			GGDebug.DebugLog("Skill difference " + num3);
			num3 *= definition.skillDifferenceReduction;
			num3 = 0f - Mathf.Min(definition.maxSkillDifference, Mathf.Abs(num3));
			GGDebug.DebugLog("Skill difference " + num3 + " max skill Difference " + definition.maxSkillDifference);
		}
		HitParamsDB.TimingRange timingRange = ScriptableObjectSingleton<HitParamsDB>.instance.timing.GetTimingRange(num2, num3, ball.flightSequence.flightTime);
		GGDebug.DebugLog("Timing: " + num2 + " range message: " + timingRange.message);
		float normTiming = ScriptableObjectSingleton<HitParamsDB>.instance.timing.GetNormTiming(num2, ball.flightSequence.flightTime);
		float quality = (hitParams2.quality = timingRange.GetQuality(normTiming, num3));
		HitParamsDB.HitParams hitParams3 = ScriptableObjectSingleton<HitParamsDB>.instance.GetHit(hit2.type).GetHitParams(num, quality, ball.flightSequence.GetStageThatStartsFromTableSide(base.playerPosition.z), base.match.gameType.numShotsInPoint);
		float num4 = hitParams3.strength;
		float num5 = hitParams3.spin * definition.spinMult + definition.spinAdd;
		float num6 = num4;
		bool flag = hitParams3.shouldMissShot;
		float xRange = hitParams3.xRange2;
		heightAboveNet = hitParams3.heightAboveNet;
		if (!isServe)
		{
			heightAboveNet *= definition.heightAboveNetMult;
		}
		hitParams2.attackPoints = GetSkillPoints(skillType2);
		hitParams2.reductionFactor = hitParams3.skillPointsReductionFactor;
		hitParams2.opponentDefensePoints = hitParams3.opponentDefensePoints;
		PointsLabel pointsLabel = base.match.ui.GetPointsLabel(this);
		if (pointsLabel != null && showPoints)
		{
			pointsLabel.SetPoints(Mathf.FloorToInt((hitParams2.attackPoints - hitParams2.opponentDefensePoints + 1f) * 10f * hitParams2.reductionFactor), ball.transform.position, timingRange.color);
		}
		base.match.ui.ballFollower.SetColor(timingRange.color);
		float num7 = 0f;
		num7 = ((hit2.skillType != PlayerStatsManager.SkillType.Defence) ? definition.xRange.Random(scoreDifference) : definition.xDefenseRange.Random(scoreDifference));
		num7 = Mathf.Clamp(num7, -1f, 1f);
		num7 *= Table.halfwidth * Mathf.Sign(tableTennisPlayerBase.playerPosition.x) * xRange;
		if (isServe)
		{
			flag = false;
			num5 = 0f;
		}
		if (!flag && !isServe)
		{
			heightAboveNet *= definition.shotHeightMult;
			if (racket != null && !isServe && hitParams3.racketInfluenceGreen > 0f)
			{
				heightAboveNet *= racket.heightMult;
				if (num5 > 0f)
				{
					num5 *= racket.topspinMult;
				}
			}
		}
		float deltaTime = ((!isServe) ? 0.1f : 0.01f);
		Vector3 vector = ((!isServe) ? ball.position : servePosition);
		float f = 0f;
		if (hit != null)
		{
			vector = ball.flightSequence.PositionAt(hit.flightTimeWhenHit);
			f = Mathf.Max(0f, hit.flightTimeWhenHit - ball.flightSequence.flightTime);
		}
		ball.position = vector;
		float num8 = 0f - Mathf.Sign(vector.z);
		Vector3 vector2 = new Vector3(num7, 0f, num6 * num8 * Table.halfLength);
		if (!hitParams3.canMissSide)
		{
			vector2.x = Mathf.Clamp(vector2.x + hitParams3.xRandomRange * Table.halfwidth, 0f - Table.halfwidth, Table.halfwidth);
		}
		Vector3 normalized = (vector2 - vector).OnGround().normalized;
		SetupSearch(normalized, vector);
		search.symDeltaTime = deltaTime;
		float num9 = heightAboveNet;
		if (flag)
		{
			num4 = 0f;
		}
		float angle = 0f;
		FlightInitialConditionsSearch.MaxResult maxResult = default(FlightInitialConditionsSearch.MaxResult);
		float num10 = num9;
		for (int i = 0; i < 3; i++)
		{
			angle = FlightInitialConditionsSearch.GetAngle(num9, 0.02f, vector);
			maxResult = search.FindMaxAcceptableVelocity(angle, num5, FlightInitialConditionsSearch.OptimumSearchType.SearchMin, isServe);
			if (maxResult.simResult.resultClasification == FlightInitialConditionsSearch.SimResultClasification.In || flag)
			{
				break;
			}
			num9 += num10 + Mathf.Abs(num10) * (float)(1 << i);
		}
		FlightInitialConditionsSearch.MaxResult maxResult2 = search.FindMaxAcceptableVelocity(angle, num5, FlightInitialConditionsSearch.OptimumSearchType.SearchMax, isServe);
		float num11 = Mathf.Lerp(maxResult.magnitude, maxResult2.magnitude, num4);
		num11 = maxResult.magnitude + (maxResult2.magnitude - maxResult.magnitude) * num4;
		if (flag)
		{
			num11 *= 1.5f;
		}
		if (hitParams3.canMissSide)
		{
			normalized = (vector2 - vector + Vector3.right * hitParams3.xRandomRange * Table.halfwidth).OnGround().normalized;
			search.Setup(normalized, vector);
		}
		FlightParams initialConditions = search.GetInitialConditions(num11, angle, num5);
		FlightSimulator instance = Singleton<FlightSimulator>.instance;
		FlightSimulator.SequenceSimulationParams sim = FlightSimulator.SequenceSimulationParams.DefaultRecordFlightParams(initialConditions, symFlight);
		sim.deltaTime = deltaTime;
		instance.FillFlightSequence(ball.flightSequence, sim);
		ball.flightSequence.Reset();
		ball.flightSequence.Update(Mathf.Abs(f));
		ball.isServeBall = isServe;
		ball.playerThatHitBall = this;
		ball.hitParams = hitParams2;
		ball = null;
		PlaySound(hitParams3.range.GetClip());
		if (hitParams3.returnSpeed > 0f)
		{
			float f2 = (Mathf.Abs(base.playerPosition.z) + hitParams3.returnZAdjust) * (float)base.tableSide;
			float b = Table.halfLength * 2f;
			f2 = (float)base.tableSide * Mathf.Min(Mathf.Abs(f2), b);
			Vector3 vector3 = new Vector3(base.playerPosition.x * hitParams3.returnXAdjust, 0f, f2);
			float timeToGetToPosition = Vector3Ex.HorizontalDistance(base.playerPosition, vector3) / (hitParams3.returnSpeed * GetSpeed(base.match.gameType.numShotsInPoint));
			movePlan.MoveToPosition(base.playerPosition, vector3, null, timeToGetToPosition, 0f);
			KineticServeHitElement firstElementOfType = base.kineticPlan.GetFirstElementOfType<KineticServeHitElement>();
			if (firstElementOfType != null)
			{
				firstElementOfType.canMove = false;
			}
		}
		HitBallParamsPhysicsFlight hitBallParams = default(HitBallParamsPhysicsFlight);
		hitBallParams.missWide = flag;
		hitBallParams.hitType = (int)hit2.type;
		base.match.OnPlayerHitBall(this, hitBallParams);
	}

	protected void SetupSearch(Vector3 forwardDirection, Vector3 initPosition)
	{
		search.forwardDirection = forwardDirection.normalized;
		search.velocityMagnitudeBoundaries.max = 25f;
		search.velocityMagnitudeBoundaries.min = 0f;
		search.heightBoundaries.max = 10f;
		search.symFlight = symFlight;
		search.incomingParams.position = initPosition;
	}

	private void OnBallReturned()
	{
		HitAnimationInfo orCreateHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(HitAnimationsStateEnum.BackhandBackspin1);
		GoToHit(true, true);
	}

	private void GoToHit(bool shouldHit, bool comeClose = false)
	{
		base.kineticPlan.CancelAll();
		TableTennisPlayerBase tableTennisPlayerBase = base.match.Other(this);
		bool isBackHit = !ShouldAttack();
		animController.maxMoveSpeed = GetSpeed(base.match.gameType.numShotsInPoint);
		animController.maxJumpSpeed = GetJumpSpeed(base.match.gameType.numShotsInPoint);
		List<PlayerAnimationsController.HitPlan> hitPlans = animController.CreateHitPlans(isBackHit, base.kineticPlan, ball, symDeltaTime, comeClose);
		chosenHitPlan = animController.ChooseHitPlan(hitPlans);
		if (chosenHitPlan == null)
		{
			base.match.PlayerWillMissShot(this);
			return;
		}
		float timeToGetToPosition = chosenHitPlan.hitFlightTime - ball.flightSequence.flightTime;
		if (shouldHit && (canAlwaysHit || canHitNow))
		{
			animController.AddHitAnimation(base.kineticPlan, chosenHitPlan, ball, OnHitDelegate);
			base.match.OnPlayerChosenHitPlan(this, chosenHitPlan);
		}
		else
		{
			Quaternion rotationForHitPlan = animController.GetRotationForHitPlan(chosenHitPlan);
			HitAnimationInfo hitInfo = chosenHitPlan.hitInfo;
			Vector3 desiredPosition = chosenHitPlan.startAnimPosition + rotationForHitPlan * hitInfo.positionChange;
			movePlan.MoveToPosition(base.playerPosition, desiredPosition, hitInfo, timeToGetToPosition, chosenHitPlan.hitFlightTime);
		}
		timeToGetToPosition = chosenHitPlan.hitFlightTime - ball.flightSequence.flightTime;
		if (timeToGetToPosition > 0f)
		{
			float num = Vector3Ex.HorizontalDistance(base.playerPosition, chosenHitPlan.startAnimPosition) / timeToGetToPosition;
			if (num > 0.6f && Random.Range(0, 2) == 0)
			{
				this.WaitAndExecute(Random.Range(0.5f, 0.9f) * timeToGetToPosition, PlaySqueekSound);
			}
		}
	}

	public override void OpponentChosenHitPlan(TableTennisPlayerBase opponent, PlayerAnimationsController.HitPlan hitPlan)
	{
		base.OpponentChosenHitPlan(opponent, hitPlan);
		if (base.match.ball.isBallInGame && hitPlan.hitParams.type == HitParamsDB.HitType.Smash)
		{
			Vector3 vector = Vector3.forward * Table.halfLength * 2f * base.tableSide;
			float timeToGetToPosition = Vector3Ex.HorizontalDistance(base.playerPosition, vector) / GetSpeed(base.match.gameType.numShotsInPoint);
			movePlan.MoveToPosition(base.playerPosition, vector, null, timeToGetToPosition, 0f);
		}
	}

	private void PlaySqueekSound()
	{
		PlaySound(base.match.ball.shoeSqueek, Random.Range(0.5f, 1f));
	}

	private void OnHitDelegate(KineticElementHit hit)
	{
		PhysicsBall physicsBall = ball;
		ShootBall(false, hit);
		if (testPing)
		{
			float timeToStage = physicsBall.flightSequence.GetTimeToStage(physicsBall.flightSequence.LastStage());
			GGDebug.DebugLog(timeToStage);
			float gameTimescale = ((physicsBall.flightSequence.GetFirstStage() == physicsBall.flightSequence.LastStage()) ? 1f : (1f + pingTime * 0.001f / Time.timeScale / timeToStage));
			GGGameTime.gameTimescale = gameTimescale;
		}
	}

	private void Update()
	{
		if (!base.match.isMatchReady)
		{
			return;
		}
		KineticElementHit firstElementOfType = base.kineticPlan.GetFirstElementOfType<KineticElementHit>();
		if (firstElementOfType != null && firstElementOfType.trackFlight != null)
		{
			CancelMovePlan();
		}
		if (ballFlyingTowardsMe && firstElementOfType == null && !canAlwaysHit && canHitNow)
		{
			GoToHit(true);
		}
		if (firstElementOfType == null && movePlan.isActive)
		{
			movePlan.ellapsedTime += GGGameTime.deltaTime;
			cachedAnimator.SetBool("ServeCrouch", false);
			Vector3 vector = Vector3.Lerp(movePlan.positionWhenStartMove, movePlan.desiredPosition, movePlan.ellapsedTime / movePlan.timeToGetToPosition);
			Vector3 vector2 = (vector - base.playerPosition) / GGGameTime.deltaTime;
			base.playerPosition = vector;
			cachedAnimator.SetFloat("SpeedX", vector2.x);
			cachedAnimator.SetFloat("SpeedY", vector2.z);
			if (movePlan.ellapsedTime > movePlan.timeToGetToPosition)
			{
				CancelMovePlan();
				cachedAnimator.SetFloat("SpeedX", 0f);
				cachedAnimator.SetFloat("SpeedY", 0f);
			}
		}
	}
}
